#!/usr/local/bin/lua

dofile("helper.lua")


specDir = "specs"
--typeMapFile = "gl.tm"
glSpecFile = "gl.spec"
enumSpecFile = "enum.spec"
enumExtSpecFile = "enumext.spec"

wglSpecFile = "wgl.spec"

procAddressFunction = "glelfGetProcAddress"
local Mocking_details = 
{
	gmockMaxParams = 10,
	paramWrapperPostFix = "_paramWrapper",
	paramWrapperInstanceName = "wrapper",
	mockingInstanceName = "imp",
	mockingClassName = "FakeGL",
	mockName = "GLmock",
	fakeHeaderName = "glf.h",
	extensionLoader = "glel.h",
	hmmm = "glelf"
}

--local coreExtraParamStructs ={}
--local extExtraParamStructs ={}

function functionPrototypeName(s)
	local str = string.upper(s)
	str = "PFN" .. str .."PROC"
	return str
end

--[[
local function printFunctionDef(def)
	printf("%s %s(",def.returnType,def.functionName)
	for i , v in pairs(def.paramsTable) do
		if(i ~= 1)then printf(",")end
		printf("%s %s",v.argType,v.argName)
	end
	
	printf(")\n")
end
--]]


--local
function parseTypeMapFile(typeMapFile)
	local f = io.open(specDir .."/" .. typeMapFile,"r")
	assert(f)
	local str = f:read("*a")
	f:close()
	local typeMap = {}

	local matcher = "([%w_]*),%*,%*,%s*(.-),%*,%*"
 	for k, v in string.gmatch(str, matcher) do
       typeMap[k] = v
      --printf("type:%s mapping:%s\n",k,v)
    end
    
    --void is a special case lets fix that
    typeMap["void"]="void"
    return typeMap
end


local function createFunctionDef(namePrefix,functionDefStr,typeMap)

	--find the function name
	funcNameIndex = string.find(functionDefStr,"%(")
	name = string.sub(functionDefStr,1,funcNameIndex-1)
	name = namePrefix ..name

	--print(name)
	local endBrace = string.find(functionDefStr,"%)",funcNameIndex)
	
	
	local modifiedStr = string.sub(functionDefStr,endBrace+1,string.len(functionDefStr))

	--find the return type
	local retType = string.match(modifiedStr,"return%s*([%w_]+)%s*\n")

	retType = typeMap[retType]
	--print(retType)
	paramMatcher = "param%s+([%w_]*)%s+(.-)\n"
	
	local functionParams ={}
	
	for paramName, typeDetailStr in string.gmatch(modifiedStr, paramMatcher) do
		local paramType = string.match(typeDetailStr,"^%s*([%w_]+)")
		paramType = typeMap[paramType]
		local isArray = string.find(typeDetailStr,"array")
		if(isArray == nil)then isArray = string.find(typeDetailStr,"reference")end
		local arr=""
		if(isArray)then
			paramType = paramType.."*"
		end
		
		local functionArg =
		{
			argType = paramType,
			argName = paramName,
			specialCaseArray = arr
		}
		table.insert(functionParams,functionArg)
    end
    
    catMatcher = "category%s*([%w_]*)"
    
    local cat = string.match(modifiedStr,catMatcher)
	
	depMatcher = "deprecated%s*(%d%.%d)"
	local deprecatedInOpenGLVersion = string.match(modifiedStr,depMatcher)
	
	
	local t = 
	{
		returnType = retType,
		functionName = name,
		paramsTable = functionParams,
		deprecatedInVersion = deprecatedInOpenGLVersion,
		category = cat
	}
	return t

end


local function grab_functions_from_section(section,typeMap,namePrefix)
	local matcher = "[%w_]+%(.-%)\n%s*return.-\n\n"
	local start = 1
	sectionTable ={}
	
	while(true)do
		local defStart, defEnd = string.find(section,matcher,start)
		if(defStart and defEnd  )then
			local def = string.sub(section,defStart,defEnd)
			local defTable = createFunctionDef(namePrefix,def,typeMap)
			--printFunctionDef(defTable)
			table.insert(sectionTable,defTable)
			start = defEnd+1
		else
			break
		end
	end
	return sectionTable
end

local function splitCats(cats)
	local ver = "VERSION_(.-)%s+"
	for version in string.gmatch(cats, ver) do
		print("VERSION_"..version)
	end
end

local function addArgTypeAndName(index,definition)
	local str =""
	if(index~=1)then 
		str = str ..","
	end
	str = str .. definition.paramsTable[index].argType .. " " .. definition.paramsTable[index].argName
	return str
end
	
local function typeAndArgStrEnclosedByBraces(func)
	local str ="("
	
	for index =1, #func.paramsTable do
		str = str .. addArgTypeAndName(index,func)
	end
	str = str .. ")"
	return str
end

local function typeAndArgStrEnclosedByBraces_limitedByGmock(func)
	local str ="("
	
	if( #func.paramsTable > Mocking_details.gmockMaxParams) then
		for  i = 1 ,Mocking_details.gmockMaxParams -1 do
			str = str .. addArgTypeAndName(i,func)
		end
		str = str .. "," ..func.functionName .. Mocking_details.paramWrapperPostFix .." " .. Mocking_details.paramWrapperInstanceName
	else
		for  i = 1 ,#func.paramsTable do
			str = str .. addArgTypeAndName(i,func)
		end
	end
	str = str .. ")"
	return str
end


local function createLocalWrapperInstanceAndInit(functionDef)
	local str=""
	--more parameters than allowed with gmock, so create the wrapper instance and intialise
	if(#functionDef.paramsTable > Mocking_details.gmockMaxParams)then
		str = str .."\t" .. functionDef.functionName .. Mocking_details.paramWrapperPostFix .. " " .. Mocking_details.paramWrapperInstanceName .."= {"
		for  i = Mocking_details.gmockMaxParams ,#functionDef.paramsTable do
			if(i~=Mocking_details.gmockMaxParams)then 
				str = str .. ","
			end
			str = str .." " .. functionDef.paramsTable[i].argName
		end
		str = str .. "};\n"
	end
	return str
end

local function callMockFunctionStr(functionDef,instanceName)
	--return instance->func(params)
	local str =  "\treturn " .. instanceName .."->" .. functionDef.functionName .."("
	
	local function addArgName(index,definition)
		if(index~=1)then 
			str = str .. ","
		end
		str = str .. definition.paramsTable[index].argName
	end
	
	if(#functionDef.paramsTable > Mocking_details.gmockMaxParams) then
		for  i = 1 ,Mocking_details.gmockMaxParams -1 do
			addArgName(i,functionDef)
		end
		str = str .."," ..Mocking_details.paramWrapperInstanceName
	else
		for  i = 1 ,#functionDef.paramsTable do
			addArgName(i,functionDef)
		end
	end
	str = str ..");\n"
	return str
end


local function proxyFunction(fileHandle,functionDef,impName)
	fileHandle:write( functionDef.returnType .. " ".. functionDef.functionName) 
	fileHandle:write( typeAndArgStrEnclosedByBraces(functionDef) )
	fileHandle:write("\n{\n")
	fileHandle:write( createLocalWrapperInstanceAndInit(functionDef) )
	fileHandle:write( callMockFunctionStr(functionDef,impName) )
	fileHandle:write("}\n")
end


local function writeCoreImpFunctions(coreSections)
	local f = io.open("glCoreImp.cpp","w")
	f:write("extern \"C\"\n{\n")
	
	for sectionIndex , section in pairs(coreSections) do
		f:write("\n\n#ifdef " ..section.version .."\n")
		for index = 1, #section do
			local functionDef = section[index]
			local instanceName = Mocking_details.mockingClassName .."::" ..Mocking_details.mockingInstanceName
			proxyFunction(f,functionDef,instanceName)	
		end
		f:write("#endif //" .. section.version .. "\n")
	end
	f:write("\n}////end extern C\n")
	f:close()
end


local function writeProxyExtFunctions(coreSections)
	local f = io.open("glExtImp.cpp","w")
	f:write("extern \"C\"\n{\n")
	for sectionIndex , section in pairs(coreSections) do
		--f:write("////section version" .. section.version  or "nil" .."\n")
		for index = 1, #section do
			local functionDef = section[index]
			local instanceName = Mocking_details.mockingClassName .."::" ..Mocking_details.mockingInstanceName
			proxyFunction(f,functionDef,instanceName)	
		end
	end
	f:write("\n}////end extern C\n")
	f:close()
end

local function extra_param_struct(functionDef)
	local structStr = functionDef.functionName .. Mocking_details.paramWrapperPostFix
	structStr = structStr .. "\n{\n "
	for  i = Mocking_details.gmockMaxParams ,#functionDef.paramsTable do
		structStr = structStr .."\t" ..functionDef.paramsTable[i].argType .." " .. functionDef.paramsTable[i].argName ..";\n"
	end
	structStr = structStr .. "};\n"
	return structStr
end

local function extraParamStructs(coreSections)
	local t ={}
	for sectionIndex , section in pairs(coreSections) do
		for index = 1, #section do
		local functionDef = section[index]
			if(#functionDef.paramsTable >Mocking_details.gmockMaxParams)then
				table.insert(t, extra_param_struct(functionDef) ) 
			end
		end
	end
	return t
end


local function writeCoreFakeInterface(coreSections,extraParamWrappers)
	local f = io.open("GLfake.h","w")
	
	local fakeDefineGuard = "GL_FAKE_H_"
	f:write("#ifndef " ..fakeDefineGuard .."\n")
	f:write("#\tdefine " ..fakeDefineGuard .."\n")
	
	if(extraParamWrappers ~= nil)then
		f:write("//Param wrappers for functions with more parameters than possible with gmock\n")
		f:write("extern \"C\"\n{\n")
		for i,e in pairs(extraParamWrappers) do
			f:write(e)
		end
		f:write("}\n")
	end
	
	f:write("class " .. Mocking_details.mockingClassName .. "\n")
	f:write("{\n")
	f:write("public:\n")
	f:write("\tstatic " .. Mocking_details.mockingClassName .. "* inst;\n")
	f:write("\tvirtual ~" .. Mocking_details.mockingClassName .. "(){}\n")
	

	
	for sectionIndex , section in pairs(coreSections) do
		f:write("\t//" ..section.version .."\n")
		for index = 1, #section do
		local functionDef = section[index]
			f:write("\t"..functionDef.returnType .." ".. functionDef.functionName)
			f:write( typeAndArgStrEnclosedByBraces_limitedByGmock(functionDef) )
			f:write(" = 0; \n")
		end
		f:write("\t//end " .. section.version .. "\n\n")
	end
	
	f:write("};\n")
	f:write("#endif //end guard\n\n")
	f:close()
end

local function gmockParamCount(functionDef)
	local paramCount = #functionDef.paramsTable
	if(paramCount == nil)then print("paramtable empty? " ..functionDef.functionName)end
	if (paramCount > Mocking_details.gmockMaxParams) then
		return Mocking_details.gmockMaxParams
	else
		return paramCount
	end
end



local function writeCoreFakeMock(coreSections)
	local f = io.open("GLmock.h","w")
	
	headerGuard(f,"GLMOCK_H_")
	includeHeader(f,"gmock/gmock.h",false)
	includeHeader(f,"GLfake.h",false)
	
	f:write("class " .. Mocking_details.mockName .." : public "..  Mocking_details.mockingClassName .. "\n")
	f:write("{\n")
	f:write("public:\n")

	for sectionIndex , section in pairs(coreSections) do
		f:write("\t//" ..section.version .."\n")
		for index = 1, #section do
		local functionDef = section[index]
			f:write("\tMOCK_METHOD" .. gmockParamCount(functionDef) .. "(" ..functionDef.functionName )
			f:write("," .. functionDef.returnType .. typeAndArgStrEnclosedByBraces_limitedByGmock(functionDef) ..");\n" )
		end
		f:write("\t//end " .. section.version .. "\n\n")
	end
	
	f:write("};\n")
	f:write("#endif //end guard\n\n")
	f:close()
end



local function parse_gl_spec_file(typeMap)

	local f = io.open(specDir .."/" .. glSpecFile,"r")
	local str = f:read("*a")
	f:close()
	
	local cat = "category:"
	local ver = "version:"
	
	local catStart, catEnd = string.find(str,cat)
	local endLine = string.find(str,"\n",catEnd)
	
	print("catorgories are:")
	local cats = string.sub(str,catEnd+1,endLine-1)
	print(cats)
	splitCats(cats)
	
	local verStart,verEnd = string.find(str,ver,endLine)
	endLine = string.find(str,"\n",verEnd)
	
	print("OpenGL versions in this file are:")
	local versions = string.sub(str,verEnd+1,endLine-1)
	print(versions)
	
	
	local section_matcher = "#+\n#+\n#\n#%sOpenGL%s%d.%d.-\n#\n#+\n#+\n\n"
	
	local version_matcher = "#+\n#+\n#\n#%sOpenGL%s(%d)%.(%d).-\n#\n#+\n#+\n\n"
	
	local extension_start_matcher ="ARB extensions, in order by ARB extension number"
	

	coreSections = {}
	
	local startIndex=1
	local cont = true
	while(cont)do
		local sectionStart, sectionHeaderEnd = string.find(str,section_matcher,startIndex)
		local largeVersion, smallVersion = string.match(str,version_matcher,startIndex)

		startIndex = sectionHeaderEnd
		local sectionEnd,sectionHeaderEnd = string.find(str,section_matcher,startIndex)
		if(sectionEnd == nil or sectionHeaderEnd == nil)then
			sectionEnd,sectionHeaderEnd = string.find(str,extension_start_matcher,startIndex)
			cont = false
		end
	
		local sectionStr = string.sub(str,sectionStart,sectionEnd-1)
	
		local sectionTable = grab_functions_from_section(sectionStr,typeMap,"gl")
		sectionTable.version = "GL_VERSION_" .. largeVersion .. "_" ..smallVersion
		table.insert(coreSections,sectionTable)
	end

	--printCoreSections(coreSections)
	
	

	writeCoreImpFunctions(coreSections)

	writeCoreFakeInterface(coreSections, extraParamStructs(coreSections) )
	
	writeCoreFakeMock(coreSections)
	
	--grab ARB extensions
	local arbExtensionMatcher ="#+\n#\n#%sARB%sExtension%s#%d\n#%s[%w_]+%scommands"
	local arbExtensionCommandMatcher ="#+\n#\n#%sARB%sExtension%s#%d\n#%s([%w_]+)%scommands"
	
	
	local extensionMatcher = "#+\n#\n#%s%u*%s?Extension%s#%d*.-\n\n"
	extSections = {}
	
	startIndex = 1
	cont = true
	while(cont == true)do
		local extStart, extEnd = string.find(str,extensionMatcher,startIndex)
		--print(string.sub(str,extStart,extEnd) )
		if(extStart ~= nil and extEnd ~= nil)then

		else
			assert(nil)
		end
	
		local extNextStart, extNextEnd =  string.find(str,extensionMatcher,extEnd+1)
		if(extNextStart ~= nil and extNextEnd ~= nil)then
			local section = string.sub(str,extEnd+1,extNextStart-1)
			local sectionFuncs = grab_functions_from_section(section,typeMap,"gl")
			table.insert(extSections,sectionFuncs)
		else
			cont = false
		end
		startIndex = extNextStart

	end
	
	--printExtSections(extSections)
	writeProxyExtFunctions(extSections)
	return coreSections, extSections
end

local function allExtensionsInSectionsFromStr(str,typeMap,namePrefix)
	local extensionMatcher = "#+\n#\n#%s%u*%s?Extension%s#%d*.-\n\n"
	extSections = {}
	
	startIndex = 1
	cont = true
	while(cont == true)do
		local extStart, extEnd = string.find(str,extensionMatcher,startIndex)
		
		if(extStart == nil and extEnd == nil)then
			assert(nil)
		end
	
		local extNextStart, extNextEnd =  string.find(str,extensionMatcher,extEnd+1)
		if(extNextStart ~= nil and extNextEnd ~= nil)then
			local section = string.sub(str,extEnd+1,extNextStart-1)
			local sectionFuncs = grab_functions_from_section(section,typeMap,namePrefix)
			table.insert(extSections,sectionFuncs)
		else
			cont = false
			local section = string.sub(str,extEnd+1,string.len(str))
			--make sure it ends in double new line so that grab does not fail to match
			section = section .."\n\n" 
			local sectionFuncs = grab_functions_from_section(section,typeMap,namePrefix)
			table.insert(extSections,sectionFuncs)
		end
		startIndex = extNextStart

	end
	
	return extSections
	
end

local function parse_wglext_spec_file(typeMap)

	local f = io.open("specs/WGL/wglext.spec","r") 
	assert(f)
	local str = f:read("*a")
	f:close()
	
	return allExtensionsInSectionsFromStr(str,typeMap,"wgl")
end


local function writeExtSections(extSections,fileName)
	local f = io.open(fileName,"w")
	f:write("\n\n/*extensions*/\n")
	externCstart(f)
	for sectionIndex , section in pairs(extSections) do
		for functionIndex , functionDef in pairs(section) do
			local instanceName = Mocking_details.mockingClassName .."::" ..Mocking_details.mockingInstanceName
			proxyFunction(f,functionDef,instanceName)	
		end
	end
	externCend(f)
	f:close()
end

--[[
local function writeWglImps(extSections)
	local f = io.open("wglImp.c","w")
	f:write("\n\n/*wgl core*/\n")
	
	externCstart(f)
	for sectionIndex , section in pairs(extSections) do
		for functionIndex , functionDef in pairs(section) do
			local instanceName = Mocking_details.mockingClassName .."::" ..Mocking_details.mockingInstanceName
			proxyFunction(f,functionDef,instanceName)	
		end
	end
	externCend(f)
	f:close()
end

--]]

local function parse_wgl_spec_file(typeMap)
	
	local f = io.open(specDir .."/WGL/" .. wglSpecFile,"r")
	assert(f)
	local str = f:read("*a")
	f:close()
	
	local sectionTable = grab_functions_from_section(str,typeMap,"gl")
	local allSections={}
	table.insert(allSections,sectionTable)
	--printWglSection(allSections)
	return allSections
end


local function parse_glx_spec_file(typeMap,specfile)
	
	local f = io.open(specDir .."/" ..specfile,"r")
	assert(f)
	local str = f:read("*a")
	f:close()
	--ensure it finishes with double new line
	str = str .."\n\n"
	local sectionTable = grab_functions_from_section(str,typeMap,"gl")
	local allSections={}
	table.insert(allSections,sectionTable)
	--printWglSection(allSections)
	return allSections
end



local function makeAndFixWglTypeMap()
	local wglTypeMap = parseTypeMapFile("WGL/wgl.tm")

	wglTypeMap["PIXELFORMATDESCRIPTOR"]="PIXELFORMATDESCRIPTOR"
	wglTypeMap["LAYERPLANEDESCRIPTOR"]="LAYERPLANEDESCRIPTOR"
	wglTypeMap["COLORREF"]="const COLORREF"
	wglTypeMap["PROC"]="PROC"
	wglTypeMap["LPCSTR"]="LPCSTR"
	return wglTypeMap
end

local function makeAndFixGlxTypeMap()
	local all= parseTypeMapFile("gl.tm")
	local glxTypeMap = parseTypeMapFile("GLX/glx.tm")
	
	for k,v in pairs(glxTypeMap)do
		if(all[k]==nil)then
			all[k] = glxTypeMap[k]
		end
	end
	all["GLXHyperpipeNetworkPointer"]="GLXHyperpipeNetworkSGIX *"
	all["GLXHyperpipeConfigPointer"]="GLXHyperpipeConfigSGIX *"
	all["GLXHyperpipeConfig"] = "GLXHyperpipeConfigSGIX"
	return all
end

local function parse_glxext_spec_file(typeMap)
	local f = io.open("specs/GLX/glxext.spec","r") 
	assert(f)
	local str = f:read("*a")
	f:close()
	
	return allExtensionsInSectionsFromStr(str,typeMap,"glX")

end

local function glextLoadFunction()
	local str = "typedef void(*GLelf_proc)();\n"
	str = str .."GLelf_proc "..procAddressFunction .."(char * name);\n"
	return str
end

local function glextLoadFunctionImp()
	local str = "GLelf_proc "..procAddressFunction .."(char * name)\n{\n"
	str = str .."#ifdef WINDOWS_BUILD\n"
	str = str .."\treturn (GLelf_proc)wglGetProcAddress(name);\n"
	str = str .. "#elif defined UNIX_BUILD || defined MAC_BUILD\n"
	str = str .."\treturn (GLelf_proc)glXGetProcAddress/*ARB*/(name);\n"
	str = str .."else \n#\terror unknown config\n"
	str = str .."}\n#endif\n"
	return str
end

local functionPresentPostfix = "_is_present"

local function loader_header(glExt, wglExt,glxExt)
	local f = io.open("ext_loader.h","w")
	
	
	for sectionIndex , section in pairs(glExt) do
		for index = 1, #section do
			if(index ==1 )then f:write("/*" ..section[index].category .."*/\n")end
			f:write("extern int " .. section[index].functionName .. functionPresentPostfix .. ";\n")
		end
	end
	
	f:write("#ifdef WINDOWS_BUILD\n")
	for sectionIndex , section in pairs(wglExt) do
		for index = 1, #section do
		if(index ==1 )then f:write("/*" ..section[index].category .."*/\n")end
			f:write("extern int " .. section[index].functionName .. functionPresentPostfix .. ";\n")
		end
	end
	f:write("#endif\n")
	
	f:write("#if defined MAC_BUILD\n")
	for sectionIndex , section in pairs(glxExt) do
		for index = 1, #section do
		if(index ==1 )then f:write("/*" ..section[index].category .."*/\n")end
			f:write("extern int " .. section[index].functionName .. functionPresentPostfix .. ";\n")
		end
	end
	f:write("#endif\n")
	f:close()
end


local function extSectionLoaderFunction(fileHandle,section)

	for index = 1, #section do
		if(index ==1 )then 
			--fileHandle:write("/*" ..section[index].category .."*/\n")
			fileHandle:write("int "..section[1].category .. "_load()\n{\n")	
		end
		fileHandle:write(section[index].functionName .. "= (" ..functionPrototypeName(section[index].functionName) ..")")
		fileHandle:write( procAddressFunction .."(\""..section[index].functionName.."\");\n")
			
		if(index == #section)then
			fileHandle:write("\treturn -1;\n")
			fileHandle:write("}\n")
		end
	end

end

local function loader_source(glExt, wglExt,glxExt)
	local f = io.open("ext_loader.cpp","w")
	
	
	for sectionIndex , section in pairs(glExt) do
	--[[
		for index = 1, #section do
			if(index ==1 )then 
				f:write("/*" ..section[index].category .."*/\n")
				f:write("int "..section[1].category .. "_load()\n{\n")
			end
			f:write(section[index].functionName .. "= (" ..functionPrototypeName(section[index].functionName) ..")")
				f:write( procAddressFunction .."(\""..section[index].functionName.."\");\n")
			
			if(index == #section)then
				f:write("\treturn -1;\n")
				f:write("}\n")
			end
			extSectionLoaderFunction(f,section)
		end
	--]]
		extSectionLoaderFunction(f,section)
	end
	
	f:write("#ifdef WINDOWS_BUILD\n")
	for sectionIndex , section in pairs(wglExt) do
	--[[
		for index = 1, #section do
		if(index ==1 )then f:write("/*" ..section[index].category .."*/\n")end
			f:write("extern int " .. section[index].functionName .. functionPresentPostfix .. ";\n")
		end
	--]]
		extSectionLoaderFunction(f,section)
	end
	f:write("#endif\n")
	
	f:write("#if defined MAC_BUILD\n")
	for sectionIndex , section in pairs(glxExt) do
	--[[
		for index = 1, #section do
		if(index ==1 )then f:write("/*" ..section[index].category .."*/\n")end
			f:write("extern int " .. section[index].functionName .. functionPresentPostfix .. ";\n")
		end
	--]]
		extSectionLoaderFunction(f,section)
	end
	f:write("#endif\n")
	f:close()
end

---[[
coreTypeMap = parseTypeMapFile("gl.tm")
local glCore, glExt = parse_gl_spec_file(coreTypeMap)
--]]

--windows specific
---[[
local wglTypeMap = makeAndFixWglTypeMap()
local wglSections = parse_wgl_spec_file(wglTypeMap)
writeExtSections(wglSections,"wglImp.cpp")
--]]

---[[
local wglExt = parse_wglext_spec_file(wglTypeMap)
writeExtSections(wglExt,"wglExtImp.cpp")
--]]

--X11 specific
---[[
local glxTypeMap = makeAndFixGlxTypeMap()
local glxSections = parse_glx_spec_file(glxTypeMap,"GLX/glx.spec")
writeExtSections(glxSections,"glxImp.cpp")
--]]
---[[
--implement this function
local glxExt = parse_glxext_spec_file(glxTypeMap)
writeExtSections(glxExt,"glxExpImp.cpp")
--]]


loader_header(glExt,wglExt,glxExt)
loader_source(glExt,wglExt,glxExt)